using System;
using System.Collections;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using AccountingLibs;
namespace Lists
{
    public class VatTuHangHoa : DoiTuong
    {
        #region Ma property
        public string Ma
        {
            get
            {
                return (string)_DataRow["Ma"];
            }
            set
            {
                _DataRow["Ma"] = value;
            }
        }
        #endregion

        #region Ten property
        public string Ten
        {
            get
            {
                return (string)_DataRow["Ten"];
            }
            set
            {
                _DataRow["Ten"] = value;
            }
        }
        #endregion

        #region DonViTinh property
        public string DonViTinh
        {
            get
            {
                return (string)_DataRow["DonViTinh"];
            }
            set
            {
                _DataRow["DonViTinh"] = value;
            }
        }
        #endregion

        #region NhomVatTuHangHoa property
        public NhomVatTuHangHoa NhomVatTuHangHoa
        {
            get
            {
                if (_DataRow["NhomVatTuHangHoaID"] is Guid)
                    return DanhMucNhomVatTuHangHoa.Instance.GetByID((Guid)_DataRow["NhomVatTuHangHoaID"]);
                else
                    return null;
            }
            set
            {
                if (value is NhomVatTuHangHoa)
                    _DataRow["NhomVatTuHangHoaID"] = value.ID;
                else
                    _DataRow["NhomVatTuHangHoaID"] = DBNull.Value;
            }
        }
        #endregion

        #region GiaMuaHienTai property
        public decimal GiaMuaHienTai
        {
            get
            {
                return (decimal)_DataRow["GiaMuaHienTai"];
            }
            set
            {
                _DataRow["GiaMuaHienTai"] = value;
            }
        }
        #endregion

        #region GiaBanHienTai property
        public decimal GiaBanHienTai
        {
            get
            {
                return (decimal)_DataRow["GiaBanHienTai"];
            }
            set
            {
                _DataRow["GiaBanHienTai"] = value;
            }
        }
        #endregion

        #region GiaBia property
        public decimal GiaBia
        {
            get
            {
                if (_DataRow["GiaBia"] is decimal)
                    return (decimal)_DataRow["GiaBia"];
                else return 0;
            }
            set
            {
                _DataRow["GiaBia"] = value;
            }
        }
        #endregion

        #region ChietKhau property
        public int ChietKhau
        {
            get
            {
                if (_DataRow["ChietKhau"] is int)
                    return (int)_DataRow["ChietKhau"];
                else return 0;
            }
            set
            {
                _DataRow["ChietKhau"] = value;
            }
        }
        #endregion

        #region NhaXuatBan property
        public string NhaXuatBan
        {
            get
            {
                if (_DataRow["NhaXuatBan"] is string)
                {
                    return (string)_DataRow["NhaXuatBan"];
                }
                else return "";
            }
            set
            {
                _DataRow["NhaXuatBan"] = value;
            }
        }
        #endregion

        #region NguonCungCap property
        public string NguonCungCap
        {
            get
            {
                if (_DataRow["NguonCungCap"] is string)
                {
                    return (string)_DataRow["NguonCungCap"];
                }
                else return "";
            }
            set
            {
                _DataRow["NguonCungCap"] = value;
            }
        }
        #endregion

        #region TacGia property
        public string TacGia
        {
            get
            {
                if (_DataRow["TacGia"] is string)
                {
                    return (string)_DataRow["TacGia"];
                }
                else return "";
            }
            set
            {
                _DataRow["TacGia"] = value;
            }
        }
        #endregion

        #region GiaXuatKhoTamTinh property
        public decimal GiaXuatKhoTamTinh
        {
            get
            {
                return (decimal)_DataRow["GiaXuatKhoTamTinh"];
            }
            set
            {
                _DataRow["GiaXuatKhoTamTinh"] = value;
            }
        }
        #endregion

        #region TrangThai property
        public bool TrangThai
        {
            get
            {
                return (bool)_DataRow["TrangThai"];
            }
            set
            {
                _DataRow["TrangThai"] = value;
            }
        }
        #endregion

        public VatTuHangHoa(DataRow dataRow)
            : base(dataRow)
        {
            this.TrangThai = true;
        }

        public static decimal CalculateGiaXuatKho(Guid vatTuHangHoaID, Guid khoID, DateTime thoiDiemXuat, decimal soLuong)
        {
            SqlConnection con = new SqlConnection(AccountingLibs.LocalSettings.ConnectString);
            try
            {
                con.Open();
                SqlCommand cmd = con.CreateCommand();
                cmd.CommandText = "Select_GiaVonHangXuat_FIFO";
                cmd.CommandType = CommandType.StoredProcedure;
                decimal donGiaXuat = 0;
                cmd.Parameters.AddWithValue("VatTuHangHoaID", vatTuHangHoaID);
                cmd.Parameters.AddWithValue("KhoID", khoID);
                cmd.Parameters.AddWithValue("ThoiDiemXuat", thoiDiemXuat);
                cmd.Parameters.AddWithValue("SoLuong", soLuong);
                cmd.Parameters.AddWithValue("DonGiaXuat", donGiaXuat);
                cmd.Parameters["DonGiaXuat"].Direction = ParameterDirection.Output;
                cmd.ExecuteNonQuery();
                donGiaXuat = (decimal)cmd.Parameters["DonGiaXuat"].Value;
                return donGiaXuat;
            }
            catch (SqlException ex)
            {
                return -1;
            }
            finally
            {
                con.Close();
            }
        }
    }

    public class DanhMucVatTuHangHoa : DanhMucDoiTuong, IEnumerable
    {
        #region Instance property: Singleton Design pattern
        private static DanhMucVatTuHangHoa _Instance;
        public static DanhMucVatTuHangHoa Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new DanhMucVatTuHangHoa();
                    UniqueConstraint uniqueConstraint = new UniqueConstraint(_Instance.DataTable.Columns["Ma"]);
                    _Instance.DataTable.Constraints.Add(uniqueConstraint);
                    _Instance.DataView = _Instance.DataTable.DefaultView;
                    _Instance.DataView.Sort = "Ma";
                }
                return _Instance;
            }
        }
        #endregion

        #region override TableName property
        public override string TableName
        {
            get
            {
                return "VatTuHangHoa";
            }
        }
        #endregion

        #region Methods required by IEnumerable (use for foreach)
        public IEnumerator GetEnumerator()
        {
            return new TokenEnumerator(this);
        }

        private class TokenEnumerator : IEnumerator
        {
            private int _Position = -1;
            DanhMucDoiTuong _Dstk;

            public TokenEnumerator(DanhMucDoiTuong dstk)
            {
                _Dstk = dstk;
            }

            // Declare the MoveNext method required by IEnumerator:
            public bool MoveNext()
            {
                if (_Position < _Dstk.DataView.Count - 1)
                {
                    _Position++;
                    return true;
                }
                else
                {
                    return false;
                }
            }

            // Declare the Reset method required by IEnumerator:
            public void Reset()
            {
                _Position = -1;
            }

            // Declare the Current property required by IEnumerator:
            public object Current
            {
                get
                {
                    return new VatTuHangHoa((_Dstk.DataView[_Position].Row));
                }
            }
        }
        #endregion

        public VatTuHangHoa this[int index]
        {
            get
            {
                if (0 <= index && index <= this.Count)
                {
                    return new VatTuHangHoa(DataTable.Rows[index]);
                }
                else
                {
                    return null;
                }
            }
        }

        public VatTuHangHoa NewDoiTuong()
        {
            return new VatTuHangHoa(DataTable.NewRow());
        }

        public VatTuHangHoa GetByProperty(string property, object value)
        {
            try
            {
                DataRow[] rows = GetDataRows(property, value);
                if (rows.Length > 0) return new VatTuHangHoa(rows[0]);
                else return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public VatTuHangHoa GetByID(Guid objID)
        {
            return GetByProperty("ID", objID);
        }

        public static DanhMucVatTuHangHoa GetAll()
        {
            return Instance;
        }

        public static DanhMucVatTuHangHoa Filter(string filterExpression)
        {
            DanhMucVatTuHangHoa obj = new DanhMucVatTuHangHoa();
            obj.DataView = new DataView(DanhMucVatTuHangHoa.Instance.DataTable, filterExpression, "Ma", DataViewRowState.CurrentRows);
            return obj;
        }

        public static DanhMucVatTuHangHoa GetDanhMucDichVu()
        {
            Hashtable htNhom = new Hashtable();
            string listNhomID = "";
            foreach (NhomVatTuHangHoa nhomVatTuHangHoa in DanhMucNhomVatTuHangHoa.Filter("LienQuanDenKho = 0"))
            {
                if (!htNhom.ContainsKey(nhomVatTuHangHoa.ID))
                {
                    htNhom.Add(nhomVatTuHangHoa.ID, null);
                    listNhomID += "CONVERT('{" + nhomVatTuHangHoa.ID + "}','System.Guid'), ";

                }
            }
            string filerExpression = "";
            if (listNhomID.EndsWith(", ")) filerExpression = string.Format("NhomVatTuHangHoaID IN ({0})", listNhomID.Substring(0, listNhomID.Length - 2));
            else filerExpression = "NhomVatTuHangHoaID IS NULL";

            return Filter(filerExpression);
        }

        public static DanhMucVatTuHangHoa GetDanhMucHangHoa()
        {
            Hashtable htNhom = new Hashtable();
            string listNhomID = "";
            foreach (NhomVatTuHangHoa nhomVatTuHangHoa in DanhMucNhomVatTuHangHoa.Filter("LienQuanDenKho = 1"))
            {
                if (!htNhom.ContainsKey(nhomVatTuHangHoa.ID))
                {
                    htNhom.Add(nhomVatTuHangHoa.ID, null);
                    listNhomID += "CONVERT('{" + nhomVatTuHangHoa.ID + "}','System.Guid'), ";

                }
            }
            string filerExpression = "";
            if (listNhomID.EndsWith(", ")) filerExpression = string.Format("NhomVatTuHangHoaID IN ({0})", listNhomID.Substring(0, listNhomID.Length - 2));
            else filerExpression = "NhomVatTuHangHoaID IS NULL";

            return Filter(filerExpression);
        }

        public static DanhMucVatTuHangHoa GetDanhMucHangHoa(Guid phuongPhapTinhGiaTonKhoID)
        {
            Hashtable htNhom = new Hashtable();
            string listNhomID = "";
            foreach (NhomVatTuHangHoa nhomVatTuHangHoa in DanhMucNhomVatTuHangHoa.Filter(string.Format("LienQuanDenKho = 1 AND PhuongPhapTinhGiaTonKhoID = '{0}'", phuongPhapTinhGiaTonKhoID))) 
            {
                if (!htNhom.ContainsKey(nhomVatTuHangHoa.ID))
                {
                    htNhom.Add(nhomVatTuHangHoa.ID, null);
                    listNhomID += "CONVERT('{" + nhomVatTuHangHoa.ID + "}','System.Guid'), ";

                }
            }
            string filerExpression = "";
            if (listNhomID.EndsWith(", ")) filerExpression = string.Format("NhomVatTuHangHoaID IN ({0})", listNhomID.Substring(0, listNhomID.Length - 2));
            else filerExpression = "NhomVatTuHangHoaID IS NULL";

            return Filter(filerExpression);
        }

        public static DataTable GetDanhMucHangHoaTraLaiTheoNhaCungCap(Guid doiTuongNghiepVu1ID)
        {
            if (doiTuongNghiepVu1ID == null) return null;
            else
            {
                SqlConnection con = new SqlConnection(LocalSettings.ConnectString);
                try
                {
                    con.Open();
                    string sql = string.Format("SELECT * FROM VatTuHangHoa \n" +
                                                "WHERE ID in (SELECT VatTuHangHoa1ID FROM KhoanMucChungTu \n" +
                                                "            WHERE ChungTuID in (SELECT ChungTuID FROM ChungTu \n" +
                                                "                                WHERE ChungTuGocID in(SELECT ChungTuID FROM ChungTu A \n" +
                                                "	                                                    WHERE DoiTuongNghiepVu1ID = '{0}' and LoaiChungTuID in \n" +
                                                "	                                                    (SELECT ID FROM LoaiChungTu WHERE Ma='HoaDonMuaHang')\n" +
                                                "                                                   )\n" +
                                                "                                )\n" +
                                                "            )", doiTuongNghiepVu1ID);
                    SqlCommand cmd = new SqlCommand(sql, con);
                    SqlDataAdapter da = new SqlDataAdapter();
                    da.SelectCommand = cmd;
                    DataTable dt = new DataTable();
                    da.Fill(dt);
                    return dt;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
        }

        #region Cac ham tinh barcode
        public static string GenBarCode(Guid nhomID)
        {
            int tailOfHashCode = Math.Abs(nhomID.GetHashCode()) % 1000;
            string strNhom = tailOfHashCode.ToString();
            while (strNhom.Length != 3)
            {
                strNhom = "0" + strNhom;
            }
            //Ma barcode chua co chek sum
            string soBarCodeChuaCheckSum, soBarCodeDaCheckSum = "";
            soBarCodeChuaCheckSum = "3" + strNhom;
            double K = Convert.ToDouble(DanhMucVatTuHangHoa.GetBarCode(soBarCodeChuaCheckSum));
            while (true)
            {
                if (K != 0)
                {
                    K = K + 1;
                    soBarCodeChuaCheckSum = K.ToString();
                }
                else
                {
                    soBarCodeChuaCheckSum = soBarCodeChuaCheckSum + "00000000";
                }

                int TongCacSoChan = 0;
                int TongCacSoLe = 0;
                for (int i = 1; i <= soBarCodeChuaCheckSum.Length; i++)
                {
                    if ((i % 2) != 0)
                    {
                        TongCacSoLe = TongCacSoLe + Convert.ToInt32(Right(Left(soBarCodeChuaCheckSum, soBarCodeChuaCheckSum.Length - i + 1), 1));
                    }
                    else
                    {
                        TongCacSoChan = TongCacSoChan + Convert.ToInt32(Right(Left(soBarCodeChuaCheckSum, soBarCodeChuaCheckSum.Length - i + 1), 1));
                    }
                }

                int CheckSum;
                CheckSum = (TongCacSoChan + TongCacSoLe * 3) % 10;
                if (CheckSum != 0)
                {
                    CheckSum = 10 - CheckSum;
                }

                soBarCodeDaCheckSum = soBarCodeChuaCheckSum + CheckSum;

                //kiem tra xem da ton tai ma nay chua
                VatTuHangHoa vthh = DanhMucVatTuHangHoa.Instance.GetByProperty("Ma", soBarCodeDaCheckSum);
                if (vthh == null) return soBarCodeDaCheckSum;
                //neu da ton tai thi tiep tuc
            }
        }
        private static string GetBarCode(string ma)
        {
            try
            {
                SqlConnection con = new SqlConnection(AccountingLibs.LocalSettings.ConnectString);
                SqlCommand cmd1 = con.CreateCommand();
                cmd1.Connection.Open();
                cmd1.CommandText = string.Format("SELECT MAX(LEFT(Ma,12)) AS Ma FROM VatTuHangHoa WHERE Ma LIKE '{0}%'", ma);
                cmd1.Parameters.Clear();
                SqlDataReader dr = cmd1.ExecuteReader();
                string str = "0";
                if (dr.Read())
                {
                    if (dr["Ma"].ToString() != "")
                    {
                        str = dr["Ma"].ToString();
                    }
                }
                return str;
            }
            catch (SqlException sqlEx)
            {
                throw new Exception(CommonLib.GetSqlExceptionMessage(sqlEx));
            }

        }
        private static string Left(string param, int length)
        {
            string result = param.Substring(0, length);
            return result;
        }
        private static string Right(string param, int length)
        {
            string result = param.Substring(param.Length - length, length);
            return result;
        }

        ////quanxu lam them kiem tra xem co ma trong danh muc chua
        //public bool IsExistedBarCode(string ma)
        //{
        //    VatTuHangHoa vatTuHangHoa = this.GetByProperty("Ma", ma);
        //    return vatTuHangHoa != null;
        //}
        #endregion
    }
}
